package com.dxb.test.bitmap;

public class ChengcBitmap {
    public static void main(String[] args) {
        ChengcBitmap chengcBitmap = new ChengcBitmap(32);
        chengcBitmap.atPut(0, true);
    }

    // 存放的bit位数
    private int sizeInBits;
    // 存放数据的int数组
    private int[] data;

    /**
     * 构造方法
     *
     * @param sizeInBits
     */
    public ChengcBitmap(int sizeInBits) {
        this.sizeInBits = sizeInBits;
        int sizeInBytes = this.sizeInBytes(sizeInBits);
        this.data = new int[sizeInBytes];
    }

    /**
     * 给指定bit设置boolean值
     *
     * @param offset
     * @param value
     */
    public void atPut(int offset, boolean value) {
        if (offset + 1 > sizeInBits) {
            try {
                throw new Exception("offset can`t be greater than " + (sizeInBits - 1));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        int index = this.sizeInBytes(offset) - 1;
        int pos = 1 << (offset - 32 * index - 1);
        if (value) {
            this.data[index] |= pos;
        } else {
            this.data[index] &= (~pos);
        }
    }

    /**
     * 清理某个bit位的值
     *
     * @param offset
     */
    public void clear(int offset) {
        if (offset + 1 > sizeInBits) {
            try {
                throw new Exception("offset can`t be greater than " + (sizeInBits - 1));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        int index = this.sizeInBytes(offset) - 1;
        int pos = 1 << (offset - 32 * index - 1);
        this.data[index] &= (~pos);
    }

    /**
     * 获取指定bit的boolean值
     *
     * @param offset
     * @return 指定bit的boolean值
     */
    public boolean at(int offset) {
        if (offset + 1 > sizeInBits) {
            try {
                throw new Exception("offset can`t be greater than " + (sizeInBits - 1));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        int index = this.sizeInBytes(offset) - 1;
        int pos = 1 << (offset - 32 * index - 1);
        return ((data[index] & pos) != 0);
    }

    /**
     * 通过给定的bit位数计算需要多少字节来存储
     *
     * @param sizeInBits
     * @return 给定的bit位数计算需要多少字节来存储
     */
    private int sizeInBytes(int sizeInBits) {
        if (sizeInBits <= 32) {
            return 1;
        }
        int basic = sizeInBits / 32;
        return sizeInBits % 32 == 0 ? basic : basic + 1;
    }
}
